package com.my.mvvmrapid.ui.fuction.aissocket;

import android.os.Bundle;
import android.util.Log;

import com.my.mvvmrapid.BR;
import com.my.mvvmrapid.R;
import com.my.mvvmrapid.databinding.ActivityAisSocketBinding;
import com.zhongjh.mvvmrapid.base.ui.BaseActivity;
import com.zhongjh.mvvmrapid.utils.ToastUtils;
import com.zhongjh.mvvmrapid.utils.ScreenUtil;

import org.jetbrains.annotations.NotNull;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * 用于直接复制
 *
 * @author zhongjh
 * @date 2021/4/15
 */
public class AisSocketActivity extends BaseActivity<ActivityAisSocketBinding, AisSocketViewModel> {

    private static final String TAG = AisSocketActivity.class.getSimpleName();

    /**
     * Socket变量
     */
    private Socket mSocket;
    /**
     * 输入流对象
     */
    InputStream mInputStream;
    /**
     * 输入流读取器对象
     */
    InputStreamReader mInputStreamReader;

    BufferedReader mBufferedReader;

    /**
     * 接收服务器发送过来的消息
     */
    String response;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ScreenUtil.setFullScreen(AisSocketActivity.this, false);
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, mSocket == null ? "true":"false");
        if (mSocket != null) {
            try {
                mSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (mInputStream != null) {
            try {
                mInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (mInputStreamReader != null) {
            try {
                mInputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (mBufferedReader != null) {
            try {
                mBufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        super.onDestroy();
    }

    @Override
    public int initContentView(Bundle savedInstanceState) {
        return R.layout.activity_ais_socket;
    }

    @Override
    public int initVariableId() {
        return BR.viewModel;
    }

    @Override
    public boolean isStartAutoHideSoftKeyboard() {
        return false;
    }

    @Override
    public void initParam() {

    }

    @Override
    public void initData() {
        initSocket();
    }

    @Override
    public void initViewObservable() {

    }

    /**
     * 创建Socket对象 & 指定服务端的IP 及 端口号
     */
    private void initSocket() {
        mSocket = new Socket();
        // 1.被观察者
        Observable<Boolean> observable = Observable.create(emitter -> {
            try {
                // 要使用这种方式，不能直接new socket（IP,PORT），否则销毁时如果socket连接不了，依然是null的
                SocketAddress socAddress = new InetSocketAddress("192.9.98.177", 8099);
                mSocket.connect(socAddress, 5000);
            } catch (Exception ex) {
                // 如果已经关闭则忽略,如果不这样做，就会导致报异常的时候说socket已经关闭没有泄漏可言
                if (!mSocket.isClosed()) {
                    emitter.onError(ex);
                }
            }
            emitter.onNext(true);
            emitter.onComplete();
        });

        // 2.观察者
        Observer<Boolean> observer = new Observer<Boolean>() {

            @Override
            public void onSubscribe(@NotNull Disposable d) {
                // 保存连接状态
                AisSocketActivity.this.viewModel.accept(d);
            }

            // 接收发送的消息
            @Override
            public void onNext(@NotNull Boolean type) {
                // 判断客户端和服务器是否连接成功
                ToastUtils.showShort("socket状态：" + mSocket.isConnected());
                receiveSocket();
            }

            // 接受异常通知
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, e.getMessage());
            }

            // 接受发送完毕通知
            @Override
            public void onComplete() {

            }
        };

        // 3.观察者订阅被观察者
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    /**
     * 接收服务器消息
     */
    private void receiveSocket() {
        // 1.被观察者
        Observable<Boolean> observable = Observable.create(emitter -> {
            // 步骤1：创建输入流对象InputStream
            mInputStream = mSocket.getInputStream();

            // 步骤2：创建输入流读取器对象 并传入输入流对象
            // 该对象作用：获取服务器返回的数据
            mInputStreamReader = new InputStreamReader(mInputStream);
            mBufferedReader = new BufferedReader(mInputStreamReader);

            // 步骤3：通过输入流读取器对象 接收服务器发送过来的数据
            response = mBufferedReader.readLine();

            emitter.onNext(true);
            //发送完成
            emitter.onComplete();
        });

        // 2.观察者
        Observer<Boolean> observer = new Observer<Boolean>() {


            @Override
            public void onSubscribe(@NotNull Disposable d) {
                // 保存连接状态
                AisSocketActivity.this.viewModel.accept(d);
            }

            // 接收发送的消息
            @Override
            public void onNext(@NotNull Boolean type) {
                // 判断客户端和服务器是否连接成功
                ToastUtils.showShort("接收消息：" + response);
            }

            // 接受异常通知
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            // 接受发送完毕通知
            @Override
            public void onComplete() {
            }
        };

        // 3.观察者订阅被观察者
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

}
